﻿@page "/GridMasterDetail"
@layout DataProviderAccessArea<INwindDataProvider>

<DemoPageSectionComponent Id="DataGrid-MasterDetail" ShowHorizontalScrollBar="true">
    @using System.Collections.Concurrent
    @using System.Threading
    @inject NwindDataService NwindDataService
    @implements IDisposable

    @if(DataSource == null) {
        <p><em>Loading...</em></p>
    } else {
        <DxDataGrid @ref="@grid"
                    Data="@DataSource"
                    KeyFieldName="@nameof(Customer.CustomerId)"
                    AutoCollapseDetailRow="true"
                    ShowDetailRow="true"
                    SelectionMode="DataGridSelectionMode.None"
                    PageSize="4">
            <Columns>
                <DxDataGridColumn Field="@nameof(Customer.ContactName)" />
                <DxDataGridColumn Field="@nameof(Customer.CompanyName)" />
                <DxDataGridColumn Field="@nameof(Customer.City)" />
                <DxDataGridColumn Field="@nameof(Customer.Country)" />
            </Columns>
            <DetailRowTemplate Context="dataItem">
                <DxTabs>
                    <DxTabPage Text="Invoices">
                        <div class="p-3">
                            <DxDataGrid DataAsync="@GetInvoicesByCustomerAsync(dataItem)"
                                        SelectionMode="DataGridSelectionMode.None"
                                        LayoutRestoring="@GetDetailsGridLayoutRestoringDelegate(dataItem)"
                                        LayoutChanged="@GetDetailsGridLayoutChangedDelegate(dataItem)"
                                        PageSize="5">
                                <DxDataGridColumn Field="@nameof(Invoice.OrderId)" />
                                <DxDataGridDateEditColumn Field="@nameof(Invoice.OrderDate)"
                                                          DisplayFormat="d" />
                                <DxDataGridDateEditColumn Field="@nameof(Invoice.ShipName)" />
                                <DxDataGridDateEditColumn Field="@nameof(Invoice.ShippedDate)"
                                                          DisplayFormat="d" />
                                <DxDataGridSpinEditColumn Field="@nameof(Invoice.UnitPrice)"
                                                          DisplayFormat="c" />
                                <DxDataGridSpinEditColumn Field="@nameof(Invoice.Quantity)" />
                            </DxDataGrid>
                        </div>
                    </DxTabPage>
                    <DxTabPage Text="Contact Info">
                        <div class="p-3">
                            <DxFormLayout>
                                <DxFormLayoutItem Caption="Address:" ColSpanMd="12">
                                    @dataItem.Address
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="Postal Code:" ColSpanMd="6">
                                    @dataItem.PostalCode
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="Region:" ColSpanMd="6">
                                    @dataItem.Region
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="City:" ColSpanMd="6">
                                    @dataItem.City
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="Country:" ColSpanMd="6">
                                    @dataItem.Country
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="Phone:" ColSpanMd="6">
                                    @dataItem.Phone
                                </DxFormLayoutItem>
                                <DxFormLayoutItem Caption="Fax:" ColSpanMd="6">
                                    @dataItem.Fax
                                </DxFormLayoutItem>
                            </DxFormLayout>
                        </div>
                    </DxTabPage>
                </DxTabs>
            </DetailRowTemplate>
        </DxDataGrid>
    }
    @code {
        IEnumerable<Customer> DataSource;
        DxDataGrid<Customer> grid;

        readonly ConcurrentDictionary<string, string> detailGridsLayoutCache = new ConcurrentDictionary<string, string>();

        protected override async Task OnInitializedAsync() {
            DataSource = await NwindDataService.GetCustomersAsync();
        }

        protected Func<CancellationToken, Task<IEnumerable<Invoice>>> GetInvoicesByCustomerAsync(Customer customer) {
            return GetCustomerInviocesAsync;

            async Task<IEnumerable<Invoice>> GetCustomerInviocesAsync(CancellationToken cancellationToken) {
                var invoices = await NwindDataService.GetInvoicesAsync(cancellationToken);
                return invoices.Where(i => i.CustomerId == customer.CustomerId);
            }
        }
        protected override void OnAfterRender(bool firstRender) {
            if(firstRender) {
                var firstCustomer = DataSource.FirstOrDefault();
                grid.DetailRows.ExpandRow(firstCustomer?.CustomerId);
            }
        }
        protected Action<IDataGridLayout> GetDetailsGridLayoutRestoringDelegate(Customer customer) {
            return (layout) => {
                if(detailGridsLayoutCache.TryGetValue(customer.CustomerId, out string previousLayoutJson))
                    layout.LoadLayout(previousLayoutJson);
            };
        }

        protected Action<IDataGridLayout> GetDetailsGridLayoutChangedDelegate(Customer customer) {
            return (layout) => {
                var layoutJson = layout.SaveLayout();
                detailGridsLayoutCache.AddOrUpdate(customer.CustomerId, layoutJson, (id, layout) => {
                    return layoutJson;
                });
            };
        }
        void IDisposable.Dispose() {
            detailGridsLayoutCache.Clear();
        }
    }
</DemoPageSectionComponent>
